#include <iostream>
#include <fstream>
#include <vector>
#include <unordered_set>
#include <unordered_map>

#include <boost/algorithm/string.hpp>
#include <glog/logging.h>

using namespace std;
int main() {
    string file_name("/home/alexaway/Desktop/MeshedReconstruction.ply");
    fstream in(file_name);

    unordered_map<int,vector<int>> index_map;
    unordered_map<string,int> real_vert;

    string str;
    int num_vert = -1, num_face = -1;
    bool begin =false;
    int i = 0, num_real_vert = 0;
    while(getline(in,str)){
        if (!begin) {
            vector<string> results;
            boost::split(results,str,[](char c){return c == ' ';});
            if(results[0].find("element") != string::npos){
                if(results[1].find("vertex") != string::npos)
                    num_vert = stoi(results[2]);
                else if(results[1].find("face") != string::npos) {
                    num_face = stoi(results[2]);
                    LOG(INFO) << "num_vert: " << num_vert << endl;
                    LOG(INFO) << "num_face: " << num_face << endl;
                    real_vert.reserve((unsigned long)num_vert);
                }
            }
            if(results[0].find("end_header") != string::npos){
                begin = true;
            }
        }else{
            if (real_vert.find(str) != real_vert.end()) {
                index_map[real_vert[str]].push_back(i++);
            }else{
                real_vert[str] = num_real_vert;
                index_map[num_real_vert++].push_back(i++);
            }
            if (i == num_vert) {
                break;
            }
        }
    }
    LOG(INFO)<<"real_num_vert: "<<num_real_vert;

    ofstream out(file_name.substr(0,file_name.find(".ply"))+".off");
    out << "OFF" <<endl;
    out << num_real_vert << " " << num_face << " " << 0 << endl;

    vector<string> out_vert((unsigned long)num_real_vert);
    for (auto it : real_vert) {
        out_vert[it.second] = it.first;
    }
    for (auto it : out_vert) {
        //out << it;
        vector<string> results;
        boost::split(results,it,[](char c){return c == ' ';});
        out << stof(results[0]) << " " << stof(results[1])
            << " " << stof(results[2]) << endl;
    }
    vector<int> out_index((unsigned long)num_vert);
    for(auto it : index_map) {
        for(auto it1 : it.second) {
            out_index[it1] = it.first;
        }
    }
    for (int k = 0; k < num_face;++k) {
        out << "3" << " " << out_index[3 * k] << " ";
        out << out_index[3* k + 1] << " ";
        out << out_index[3* k + 2] << endl;
    }

    return 0;
}